package com.haima.sage.bigdata.api.common;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.SecureRandom;
import java.util.Base64;

public class AESUtils {
    private static final String AES = "AES";

    public static String newKey() throws Exception {
        KeyGenerator keygen = KeyGenerator.getInstance(AES);
        String rule = "haima@2018";
        keygen.init(128, new SecureRandom(rule.getBytes()));
        SecretKey original_key = keygen.generateKey();
        byte[] raw = original_key.getEncoded();
        SecretKey key = new SecretKeySpec(raw, AES);
        return encryptBASE64(key.getEncoded());
    }

    public static Key getKey(String data) throws Exception {
        byte[] keyBytes = decryptBASE64(data);
        return new SecretKeySpec(keyBytes, AES);
    }

    public static String encrypt(String raw, String secret) throws Exception {
        return encrypt(raw.getBytes(), secret);
    }

    public static String encrypt(byte[] raw, String secret) throws Exception {
        Key key = getKey(secret);
        byte[] data = doFinal(raw, key, Cipher.ENCRYPT_MODE, AES);
        return encryptBASE64(data);
    }

    public static String decrypt(String raw, String secret) throws Exception {
        byte[] data = decryptBASE64(raw);
        return decrypt(data, secret);
    }

    public static String decrypt(byte[] raw, String secret) throws Exception {
        Key key = getKey(secret);
        return decrypt(raw, key);
    }

    public static String decrypt(byte[] raw, Key key) throws Exception {
        byte[] data = doFinal(raw, key, Cipher.DECRYPT_MODE, AES);
        return new String(data);
    }
    public static byte[] doFinal(byte[] raw, Key key, int opmode, String type) throws Exception {
        Cipher cipher = Cipher.getInstance(type);
        cipher.init(opmode, key);
        return cipher.doFinal(raw);
    }
    public static byte[] decryptBASE64(String data) {
        return Base64.getDecoder().decode(data);
    }

    public static String encryptBASE64(byte[] data) {
        return new String(Base64.getEncoder().encode(data));
    }
}
